home *** CD-ROM | disk | FTP | other *** search
/ Mac Mania 2 / MacMania 2.toast / Demo's / Tools&Utilities / Programming / FBSpriteWorld 1.05b / Project 1.05b / FBSpriteWorld.incl < prev    next >
Encoding:
Text File  |  1994-05-01  |  36.1 KB  |  1,037 lines  |  [TEXT/ZBAS]

  1. '
  2. '       FBSpriteWorld.incl by Robert Hommel
  3. '       © Copyright 1994
  4. '       All rights granted for any use whatsoever
  5. '
  6. '       version 1.01b
  7. '
  8. '       Disclaimer:  I've tested these routines quite thoroughly on my Mac
  9. '       LC running System 7.01 and FB 1.02c.  I make no promises or warranties 
  10. '       of any kind.
  11. '
  12. '*********************************************************************
  13. '
  14. COMPILE 0, _MacsBugLabels _caseInsensitive _STRResource
  15. INCLUDE FILE _aplIncl
  16. DEFSTR LONG
  17. DEFINT A-Z
  18. '
  19. '--------------------------- GLOBALS ---------------------------------
  20. '
  21. GLOBALS "FBSpriteWorld.glbl"
  22. END GLOBALS
  23. '
  24. '------------------------- INCLUDE FILES -----------------------------
  25. '
  26. INCLUDE "TimeManager.incl"
  27. INCLUDE "GraphicUtils.incl"
  28. '
  29. '--------------------------- FUNCTIONS -------------------------------
  30. '
  31. '---------------------------------------------------------------------
  32. '       SWEnterSpriteWorld
  33. '---------------------------------------------------------------------
  34. '
  35. '       Make sure we can run in this environment.
  36. '
  37. LOCAL MODE
  38. LOCAL FN SWEnterSpriteWorld
  39.   LONG IF SYSTEM(_sysVers) > 700 AND SYSTEM(_maxColors) = 32
  40.     tmp = FN GESTALT(_gestaltTimeMgrVersion)
  41.     IF tmp < _gestaltStandardTimeMgr THEN err=_swTimeMgrNotPresent ELSE err=_noErr
  42.   XELSE
  43.     err = _swNotSystemSeven
  44.   END IF
  45. END FN = err
  46. '
  47. '---------------------------------------------------------------------
  48. '       SWGetBestPort
  49. '---------------------------------------------------------------------
  50. '
  51. '       Returns a pointer to a grafport based on the current screen depth.
  52. '
  53. LOCAL MODE
  54. LOCAL FN SWGetBestPort&(rectPtr&)
  55.   'Returns a pointer to a grafport based on the current screen depth.
  56. END FN = FN GetOffScrnGWorld(rectPtr&)
  57. '
  58. '---------------------------------------------------------------------
  59. '       SWInitSpriteWorld
  60. '---------------------------------------------------------------------
  61. '
  62. '     Given a valid SpriteWorld pointer, this function creates all 
  63. '     associated frames and sets the boundsRect.  Returns appropriate
  64. '     error code.
  65. '
  66. LOCAL MODE
  67. LOCAL FN SWCreateSpriteWorld(spriteWorldPtr&,srcPort&,rectPtr&,pictHdl&)
  68.   '
  69.   spriteWorldPtr&.boundsRect%;8   = rectPtr&      'set boundsRect
  70.   '
  71.   spriteWorldPtr&.windowFramePtr& = srcPort&      'set windowFrame
  72.   '
  73.   offPort& = FN SWGetBestPort&(rectPtr&)          'create backFrame
  74.   LONG IF offPort&
  75.     err = _NoErr                                  'initialize function return var
  76.     spriteWorldPtr&.backFramePtr&=offPort&        'create loadFrame
  77.     offPort& = FN SWGetBestPort&(rectPtr&)
  78.     LONG IF offPort&
  79.       spriteWorldPtr&.loadFramePtr& = offPort&
  80.       spriteWorldPtr&.backpictHdl&  = pictHdl&    'set backPict
  81.     XELSE
  82.       err = _swOutOfMemory
  83.     END IF
  84.   XELSE
  85.     err = _swOutOfMemory
  86.   END IF
  87.   '
  88. END FN = err
  89. '
  90. '---------------------------------------------------------------------
  91. '       SWCreateSWFromWindow
  92. '---------------------------------------------------------------------
  93. '
  94. LOCAL MODE
  95. LOCAL FN SWCreateSWFromWindow(spriteWorldPtr&,srcPort&)
  96.   '
  97.   '     Creates all associated frames and boundsRect based on a window's
  98.   '     grafPort.  Returns appropriate error code.
  99.   '
  100.   CALL GETGWORLD(CurrPort&,CurrDev&)
  101.   CALL SETGWORLD(srcPort&,0)
  102.   '
  103.   LONG IF spriteWorldPtr& = _nil                  'did we get it?
  104.     err = _swOutOfMemory                          'couldn't allocate pointer
  105.   XELSE                                           'got it!
  106.     pictHdl& = USR GETPICT(#srcPort&+_portRect)   'take snapshot of background
  107.     '   initialize the new SpriteWorld based on the window
  108.     err = FN SWCreateSpriteWorld(spriteWorldPtr&,srcPort&,srcPort&+_portRect,pictHdl&)
  109.   END IF
  110.   '
  111.   CALL SETGWORLD(CurrPort&,CurrDev&)
  112. END FN = err
  113. '
  114. '---------------------------------------------------------------------
  115. '       SWDisposFrame
  116. '---------------------------------------------------------------------
  117. '
  118. LOCAL MODE
  119. LOCAL FN SWDisposFrame(framePtr&)
  120.   CALL DISPOSEGWORLD(framePtr&.imageMapPtr&)
  121.   CALL DISPOSEGWORLD(framePtr&.maskMapPtr&)
  122. END FN = _NoErr
  123. '
  124. '---------------------------------------------------------------------
  125. '       SWDisposSprite
  126. '---------------------------------------------------------------------
  127. '
  128. '     Disposes of mask region, removes time and frame tasks, and (optionally)
  129. '     removes all frames associated with spritePtr&.
  130. '
  131. LOCAL MODE
  132. LOCAL FN SWDisposSprite(spritePtr&,removeFrames)
  133.   osErr = 0
  134.   CALL DISPOSERGN(spritePtr&.maskRegionHdl&)      'dispose mask region
  135.   
  136.   FN RmvTime(spritePtr&+_frameTimeTask&)          'remove time tasks
  137.   FN RmvTime(spritePtr&+_moveTimeTask&)
  138.   '
  139.   '     if removeFrames = _zTrue, remove all frames contained in this Sprite
  140.   '
  141.   LONG IF removeFrames
  142.     FOR frame =0 TO spritePtr&.totalFrames%-1
  143.       framePtr& = [spritePtr&+_frameList+(frame*4)]
  144.       osErr     = FN SWDisposFrame(framePtr&)
  145.       IF osErr THEN EXIT FN
  146.     NEXT
  147.   END IF
  148.   '
  149. END FN = osErr
  150. '
  151. '---------------------------------------------------------------------
  152. '       SWDisposSpriteWorld
  153. '---------------------------------------------------------------------
  154. '
  155. '     Releases memory occupied by SpriteWorld Frames and disposes of any
  156. '     sprites contained by SWPtr&.
  157. '
  158. LOCAL MODE
  159. LOCAL FN SWDisposSpriteWorld(SWPtr&)
  160.   '
  161.   osErr = _NoErr
  162.   CALL DISPOSEGWORLD(SWPtr&.backFramePtr&)        'delete backFrame
  163.   CALL DISPOSEGWORLD(SWPtr&.loadFramePtr&)        'and loadFrame...
  164.   '
  165.   FOR layer = 0 TO SWPtr&.totalLayers%-1          'delete all image and mask frames...
  166.     layerPtr&=[SWPtr&+_layerList+(layer*4)]
  167.     FOR sprite=0 TO {layerPtr&+_totalSprites}-1
  168.       spritePtr& = [layerPtr&+_spriteList+(sprite*4)]
  169.       '
  170.       '         dispose sprite and remove frames if not cloned…
  171.       '
  172.       osErr = FN SWDisposSprite(spritePtr&,spritePtr&.isClone% = 0)
  173.       IF osErr THEN EXIT FN
  174.     NEXT
  175.   NEXT
  176.   KILL PICTURE SWPtr&.backPictHdl&
  177. END FN = osErr
  178. '
  179. '---------------------------------------------------------------------
  180. '       SWUpdateSpriteWorld
  181. '---------------------------------------------------------------------
  182. '
  183. '     Copies backPict to backFrame and refreshes loadframe.
  184. '
  185. LOCAL MODE
  186. DIM tempRect.8
  187. LOCAL FN SWRefreshBackground(SWPtr&)
  188.   '
  189.   tempRect;8 = SWPtr&+_boundsRect
  190.   CALL GETGWORLD(CurrPort&,CurrDev&)
  191.   '
  192.   GW& = SWPtr&.backFramePtr&
  193.   locked = FN LOCKPIXELS(GW&.portpixmap&)
  194.   CALL SETGWORLD(GW&,0)
  195.   CALL DRAWPICTURE(SWPtr&.backPictHdl&,tempRect)  'draw picture to backFrame
  196.   CALL UNLOCKPIXELS(GW&.portpixmap&)
  197.   '
  198.   GW& = SWPtr&.loadFramePtr&
  199.   locked = FN LOCKPIXELS(GW&.portpixmap&)
  200.   CALL SETGWORLD(GW&,0)                           'refresh loadFrame with background
  201.   FN CopyOffScreenBits(SWPtr&.backFramePtr&,GW&,@tempRect,@tempRect,_srcCopy,0)
  202.   CALL UNLOCKPIXELS(GW&.portpixmap&)
  203.   '
  204.   CALL SETGWORLD(CurrPort&,CurrDev&)
  205.   '
  206. END FN
  207. '
  208. '---------------------------------------------------------------------
  209. '       SWSetBackgroundPict
  210. '---------------------------------------------------------------------
  211. '
  212. '       Sets the background PICT to pictHdl&. This background will not
  213. '       appear on the screen until you call SWRefreshBackground.
  214. '
  215. LOCAL MODE
  216. LOCAL FN SWSetBackgroundPict(SWPtr&,pictHdl&)
  217.   SWPtr&.backPictHdl& = pictHdl&
  218. END FN
  219. '
  220. '---------------------------------------------------------------------
  221. '       SWProcessSpriteWorld
  222. '---------------------------------------------------------------------
  223. '
  224. '     Sets current rect and frame for each sprite
  225. '
  226. LOCAL MODE
  227. LOCAL FN SWProcessSpriteWorld(SWPtr&)
  228.   FOR layer = 0 TO SWPtr&.totalLayers%-1
  229.     layerPtr& = [SWPtr&+_layerList+(layer*4)]
  230.     FOR sprite = 0 TO layerPtr&.totalSprites%-1
  231.       spritePtr& = [layerPtr&+_spriteList+(sprite*4)]'set current frame...
  232.       LONG IF spritePtr&.frameTTHasFired%
  233.         '
  234.         curFrame = spritePtr&.currentFrameNum% + spritePtr&.frameAdvance%
  235.         LONG IF spritePtr&.frameAdvance% > 0
  236.           IF curFrame > spritePtr&.lastFrameIndex%-1 THEN curFrame = spritePtr&.firstFrameIndex%
  237.         XELSE
  238.           IF curFrame < spritePtr&.firstFrameIndex%  THEN curFrame = spritePtr&.lastFrameIndex%-1
  239.         END IF
  240.         '
  241.         '       is there a frame change callback?
  242.         '
  243.         frameChangeProcPtr& = spritePtr&.frameChangeProcPtr&
  244.         '
  245.         '       if so, call it…
  246.         '
  247.         IF frameChangeProcPtr& THEN CALL frameChangeProcPtr&(spritePtr&,curFrame)
  248.         spritePtr&.currentFrameNum% = curFrame
  249.         '
  250.         '       update frame time task
  251.         '
  252.         LONG IF spritePtr&.frameTimeInterval% > 0
  253.           spritePtr&.frameTTHasFired% = _false
  254.           ' ••••
  255.           FN PrimeTime(spritePtr&+_frameTimeTask&,spritePtr&.frameTimeInterval%)
  256.         END IF
  257.         '
  258.         '       set draw & erase flags
  259.         '
  260.         LONG IF spritePtr&.isVisible%
  261.           spritePtr&.needsToBeDrawn%  = _zTrue
  262.           spritePtr&.needsToBeErased% = _zTrue
  263.         END IF
  264.         '
  265.       END IF
  266.       '
  267.       '         move sprite....
  268.       '
  269.       LONG IF spritePtr&.moveTTHasFired%
  270.         '
  271.         moveProcPtr& = spritePtr&.moveProcPtr&    'call moveProc
  272.         CALL moveProcPtr&(SWPtr&,spritePtr&,spritePtr&+_currentRect)
  273.         '
  274.         FN FastOffsetRect(spritePtr&.currentRect%,spritePtr&.xDelta%,spritePtr&.yDelta%)
  275.         '       update move time task
  276.         LONG IF spritePtr&.moveTimeInterval% > 0
  277.           spritePtr&.moveTTHasFired% = _false
  278.           FN PrimeTime(spritePtr&+_moveTimeTask&,spritePtr&.moveTimeInterval%)
  279.         END IF
  280.         '
  281.         '       set draw & erase flags
  282.         '
  283.         LONG IF spritePtr&.isVisible%
  284.           spritePtr&.needsToBeDrawn%    = _zTrue
  285.           spritePtr&.needsToBeErased%   = _zTrue
  286.         END IF
  287.         '
  288.       END IF
  289.     NEXT
  290.   NEXT
  291.   
  292. END FN
  293.  
  294. '---------------------------------------------------------------------
  295. '       SWAnimateSpriteWorld
  296. '---------------------------------------------------------------------
  297. '
  298. '     Draws sprites onto loadFrame and copies appropriate portions of
  299. '     loadFrame to screen.
  300. '
  301. LOCAL MODE
  302. DIM tempRect.8
  303. LOCAL FN SWAnimateSpriteWorld(SWPtr&)
  304.   '
  305.   CALL GETGWORLD(CurrPort&,CurrDev&)
  306.   '
  307.   locked = FN LOCKPIXELS(FN GETGWORLDPIXMAP(SWPtr&.loadFramePtr&))
  308.   CALL SETGWORLD(SWPtr&.loadFramePtr&,0)
  309.   '
  310.   FOR layer = 0 TO SWPtr&.totalLayers%-1          'erase sprites
  311.     layerPtr& = [SWPtr&+_layerList+(layer*4)]
  312.     FOR sprite = 0 TO layerPtr&.totalSprites%-1
  313.       spritePtr& = [layerPtr&+_spriteList+(sprite*4)]
  314.       LONG IF spritePtr&.needsToBeErased%
  315.         '       erase sprite by copying piece of backFrame to loadFrame
  316.         FN CopyOffScreenBits(SWPtr&.backFramePtr&,SWPtr&.loadFramePtr&,spritePtr&+_oldRect,spritePtr&+_oldRect,_srcCopy,_nil)
  317.         '       check to see if we erased any non-moving sprites…
  318.         FOR tgtLayer = 0 TO SWPtr&.totalLayers%-1
  319.           tgtLayerPtr& = [SWPtr&+_layerList+(tgtLayer*4)]
  320.           FOR tgtSprite = 0 TO tgtLayerPtr&.totalSprites%-1
  321.             tgtSpritePtr& = [tgtLayerPtr&+_spriteList+(tgtSprite*4)]
  322.             LONG IF tgtSpritePtr&.needsToBeDrawn%=_false AND tgtSpritePtr&.isVisible%
  323.               LONG IF FN SECTRECT(#spritePtr&+_oldRect,#tgtSpritePtr&+_currentRect,tempRect)
  324.                 '       …if so, make sure we redraw them
  325.                 tgtSpritePtr&.drawPartial% = _zTrue
  326.                 '       get union of deltaRect and tempRect (faster than UnionRect!)
  327.                 IF tgtSpritePtr&.deltaRect.top%   > tempRect.top%    THEN tgtSpritePtr&.deltaRect.top%   = tempRect.top%
  328.                 IF tgtSpritePtr&.deltaRect.left%  > tempRect.left%   THEN tgtSpritePtr&.deltaRect.left%  = tempRect.left%
  329.                 IF tgtSpritePtr&.deltaRect.bottom%< tempRect.bottom% THEN tgtSpritePtr&.deltaRect.bottom%= tempRect.bottom%
  330.                 IF tgtSpritePtr&.deltaRect.right% < tempRect.right%  THEN tgtSpritePtr&.deltaRect.right% = tempRect.right%
  331.               END IF
  332.             END IF
  333.           NEXT
  334.         NEXT
  335.       END IF
  336.     NEXT
  337.   NEXT
  338.   '
  339.   '     draw sprites in their new positions
  340.   '
  341.   FOR layer = 0 TO SWPtr&.totalLayers%-1
  342.     layerPtr& = [SWPtr&+_layerList+(layer*4)]
  343.     FOR sprite = 0 TO layerPtr&.totalSprites%-1
  344.       spritePtr& = [layerPtr&+_spriteList+(sprite*4)]
  345.       LONG IF spritePtr&.needsToBeDrawn% OR spritePtr&.drawPartial%
  346.         LONG IF spritePtr&.drawPartial%
  347.           CALL RECTRGN(spritePtr&.maskRegionHdl&,spritePtr&.deltaRect&)
  348.           maskRgnHdl& = spritePtr&.maskRegionHdl&
  349.           spritePtr&.drawPartial% = _false
  350.           spritePtr&.deltaRect.top&    = 0        'clear deltaRect
  351.           spritePtr&.deltaRect.Bottom& = 0
  352.         XELSE
  353.           maskRgnHdl& = _nil
  354.         END IF
  355.         framePtr& = [spritePtr&+_frameList+({spritePtr&+_currentFrameNum}*4)]
  356.         '       draw mask frame
  357.         FN CopyOffScreenBits(framePtr&.maskMapPtr&,SWPtr&.loadFramePtr&,framePtr&+_fBoundsRect,spritePtr&+_currentRect,_srcBic,maskRgnHdl&)
  358.         '       draw image frame
  359.         FN CopyOffScreenBits(framePtr&.imageMapPtr&,SWPtr&.loadFramePtr&,framePtr&+_fBoundsRect,spritePtr&+_currentRect,_srcOr,maskRgnHdl&)
  360.       END IF
  361.     NEXT
  362.   NEXT
  363.   '
  364.   CALL UNLOCKPIXELS(FN GETGWORLDPIXMAP(SWPtr&.loadFramePtr&))
  365.   '
  366.   CALL SETGWORLD(SWPtr&.windowFramePtr&,0)
  367.   '
  368.   '     copy loadFrame to screen
  369.   '
  370.   FOR layer = 0 TO SWPtr&.totalLayers%-1
  371.     layerPtr& = [SWPtr&+_layerList+(layer*4)]
  372.     FOR sprite = 0 TO layerPtr&.totalSprites%-1
  373.       spritePtr& = [layerPtr&+_spriteList+(sprite*4)]
  374.       LONG IF spritePtr&.needsToBeDrawn% OR spritePtr&.needsToBeErased%
  375.         'get union of oldRect and newRect (faster than UnionRect!)
  376.         IF spritePtr&.currentRect.top%    > spritePtr&.oldRect.top%    THEN spritePtr&.deltaRect.top%    = spritePtr&.oldRect.top%    ELSE spritePtr&.deltaRect.top%    = spritePtr&.currentRect.top%
  377.         IF spritePtr&.currentRect.left%   > spritePtr&.oldRect.left%   THEN spritePtr&.deltaRect.left%   = spritePtr&.oldRect.left%   ELSE spritePtr&.deltaRect.left%   = spritePtr&.currentRect.left%
  378.         IF spritePtr&.currentRect.bottom% < spritePtr&.oldRect.bottom% THEN spritePtr&.deltaRect.bottom% = spritePtr&.oldRect.bottom% ELSE spritePtr&.deltaRect.bottom% = spritePtr&.currentRect.bottom%
  379.         IF spritePtr&.currentRect.right%  < spritePtr&.oldRect.right%  THEN spritePtr&.deltaRect.right%  = spritePtr&.oldRect.right%  ELSE spritePtr&.deltaRect.right%  = spritePtr&.currentRect.right%
  380.         'set mask region equal to deltaRect
  381.         CALL RECTRGN(spritePtr&.maskRegionHdl&,#spritePtr&+_deltaRect)
  382.         FN CopyOffScreenBits(SWPtr&.loadFramePtr&,SWPtr&.windowFramePtr&,spritePtr&+_deltaRect,spritePtr&+_deltaRect,_srcCopy,spritePtr&.maskRegionHdl&)
  383.         spritePtr&.needsToBeDrawn%  = _false      'clear draw & erase flags
  384.         spritePtr&.needsToBeErased% = _false
  385.       END IF
  386.       spritePtr&.oldRect%;8 = spritePtr&+_currentRect'set old rect
  387.     NEXT
  388.   NEXT
  389.   
  390.   CALL SETGWORLD(CurrPort&,CurrDev&)
  391. END FN
  392. '
  393. '---------------------------------------------------------------------
  394. '       SWAddLayerToWorld
  395. '---------------------------------------------------------------------
  396. '
  397. '     Adds layerPtr& to specified SpriteWorld.
  398. '
  399. LOCAL MODE
  400. LOCAL FN SWAddLayerToWorld(SWPtr&,layerPtr&)
  401.   '
  402.   LONG IF SWPtr&.totalLayers%<_maxLayers
  403.     err = _NoErr
  404.     offset = SWPtr&.totalLayers%*4
  405.     POKE LONG SWPtr&+_layerList+offset,layerPtr&
  406.     INC(SWPtr&.totalLayers%)
  407.   XELSE
  408.     err=_swTooManyLayers
  409.   END IF
  410.   '
  411. END FN = err
  412. '
  413. '---------------------------------------------------------------------
  414. '       SWFrameFromPict
  415. '---------------------------------------------------------------------
  416. '
  417. '       Creates image and mask frames from specified PICT resource.
  418. '
  419. LOCAL MODE
  420. DIM frameRect.8
  421. LOCAL FN SWFrameFromPict(framePtr&,pictID)
  422.   err = _NoErr
  423.   CALL GETGWORLD(CurrPort&,CurrDev&)
  424.   '
  425.   '     create imageFrame...
  426.   '
  427.   pict& = FN GETPICTURE(pictID) : err = FN RESERROR
  428.   '
  429.   LONG IF err=_noErr
  430.     frameRect;8 = [pict&]+_picFrame
  431.     '   make sure we're at 0,0
  432.     FN FastOffsetRect(frameRect,-frameRect.left%,-frameRect.top%)
  433.     
  434.     framePtr&.fBoundsRect%;8 = @frameRect         'copy frameRect to FramePtr.fBoundsRect
  435.     
  436.     offPort& = FN SWGetBestPort&(@frameRect)      'create off screen port for image
  437.     LONG IF offPort&
  438.       framePtr&.imageMapPtr&=offPort&
  439.       locked = FN LOCKPIXELS(offPort&.portpixmap&)
  440.       CALL SETGWORLD(offPort&,0)                  'FN SetThePort(offPort&)
  441.       CALL DRAWPICTURE(pict&,frameRect)           'draw picture to imageFrame
  442.       CALL UNLOCKPIXELS(offPort&.portpixmap&)
  443.       CALL RELEASERESOURCE(pict&)
  444.     XELSE
  445.       err=_swOutOfMemory
  446.     END IF
  447.     '
  448.     '   create maskFrame...
  449.     '
  450.     pict& = FN GETPICTURE(pictID + 2) : err = FN RESERROR
  451.     '
  452.     LONG IF err=_noErr
  453.       offPort& = FN SWGetBestPort&(@frameRect)    'create off screen port for mask
  454.       LONG IF offPort&
  455.         framePtr&.maskMapPtr& = offPort&
  456.         locked = FN LOCKPIXELS(offPort&.portpixmap&)
  457.         CALL SETGWORLD(offPort&,0)                'FN SetThePort(offPort&)
  458.         CALL DRAWPICTURE(pict&,frameRect)         'draw picture to imageFrame
  459.         CALL UNLOCKPIXELS(offPort&.portpixmap&)
  460.         CALL RELEASERESOURCE(pict&)
  461.       XELSE
  462.         err=_swOutOfMemory
  463.       END IF
  464.     END IF
  465.   END IF
  466.   '
  467.   CALL SETGWORLD(CurrPort&,CurrDev&)
  468.   '
  469. END FN = err
  470. '
  471. '---------------------------------------------------------------------
  472. '       SWAddFrameToSprite
  473. '---------------------------------------------------------------------
  474. '
  475. '     Adds framePtr& to specified sprite.
  476. '
  477. LOCAL MODE
  478. LOCAL FN SWAddFrameToSprite(spritePtr&,framePtr&)
  479.   LONG IF spritePtr&.totalFrames% < _maxFrames
  480.     err = _NoErr
  481.     offset = spritePtr&.totalFrames%*4
  482.     POKE LONG spritePtr&+_frameList+offset,framePtr&
  483.     INC(spritePtr&.totalframes%)
  484.     spritePtr&.lastFrameIndex%=spritePtr&.totalFrames%
  485.   XELSE
  486.     err=_swTooManyFrames
  487.   END IF
  488. END FN = err
  489. '
  490. '---------------------------------------------------------------------
  491. '       SWInitSprite
  492. '---------------------------------------------------------------------
  493. '
  494. '     Given a pointer to a previously dimmed Sprite, sets initial values
  495. '     of a Sprite.
  496. '
  497. LOCAL MODE
  498. LOCAL FN SWInitSprite(spritePtr&,curFrame,curRectP&,boundsRectP&,vis,xDelta,yDelta,frameAdvance,ttPtr&,movePtr&)
  499.   '
  500.   spritePtr&.currentFrameNum%=curFrame
  501.   BLOCKMOVE curRectP&,spritePtr&+_currentRect,8
  502.   BLOCKMOVE curRectP&,spritePtr&+_oldRect,8
  503.   BLOCKMOVE boundsRectP&,spritePtr&+_sBoundsRect,8
  504.   spritePtr&.isVisible%                 = vis
  505.   spritePtr&.needsToBeErased%           = _false
  506.   spritePtr&.needsToBeDrawn%            = _zTrue
  507.   spritePtr&.drawPartial%               = _false
  508.   spritePtr&.totalFrames%               = 0
  509.   spritePtr&.firstFrameIndex%           = 0
  510.   spritePtr&.lastFrameIndex%            = 0
  511.   spritePtr&.xDelta%                    = xDelta
  512.   spritePtr&.yDelta%                    = yDelta
  513.   spritePtr&.maskRegionHdl&             = FN NEWRGN
  514.   spritePtr&.frameAdvance%              = frameAdvance
  515.   spritePtr&.frameTimeTask.qLink&       = _nil
  516.   spritePtr&.frameTimeTask.qType%       = 0
  517.   spritePtr&.frameTimeTask.tmAddr&      = ttPtr&
  518.   spritePtr&.frameTimeTask.tmCount&     = 0
  519.   spritePtr&.frameTimeTask.tmWakeUp&    = 0
  520.   spritePtr&.frameTimeTask.tmReserved&  = 0
  521.   spritePtr&.frameTTHasFired%           = _zTrue
  522.   spritePtr&.frameTimeInterval%         = 0
  523.   spritePtr&.frameChangeProcPtr&        = _nil
  524.   spritePtr&.moveTimeTask.qLink&        = _nil
  525.   spritePtr&.moveTimeTask.qType%        = 0
  526.   spritePtr&.moveTimeTask.tmAddr&       = ttPtr&
  527.   spritePtr&.moveTimeTask.tmCount&      = 0
  528.   spritePtr&.moveTimeTask.tmWakeUp&     = 0
  529.   spritePtr&.moveTimeTask.tmReserved&   = 0
  530.   spritePtr&.moveTTHasFired%            = _zTrue
  531.   spritePtr&.moveTimeInterval%          = 0
  532.   spritePtr&.moveProcPtr&               = movePtr&
  533.   spritePtr&.collideProcPtr&            = _nil
  534.   spritePtr&.isClone%                   = _false
  535.   '
  536.   FN InsXTime(spritePtr&.frameTimeTask&)          'install time tasks
  537.   FN InsXTime(spritePtr&.moveTimeTask&)
  538.   '
  539. END FN
  540. '
  541. '---------------------------------------------------------------------
  542. '       SWCloneSprite
  543. '---------------------------------------------------------------------
  544. '
  545. '       A cloned sprite is an exact duplicate of its source.  If you have
  546. '       assigned frames to the source sprite, the framelist of the clone
  547. '       will contain pointers to those same frames.  Thus, cloned sprites
  548. '       can share the same frames with their sources, which saves memory
  549. '       and processing time.  The isClone field is set TRUE for cloned
  550. '       sprites, so we can determine whether to remove frames from memory
  551. '       when disposing of a sprite (generally, you will only remove frames
  552. '       when disposing of a non-cloned sprite).
  553. '
  554. LOCAL MODE
  555. LOCAL FN SWCloneSprite(srcSpritePtr&,cloneSpritePtr&,ttPtr&)
  556.   '     copy srcSprite data to cloneSprite
  557.   BLOCKMOVE srcSpritePtr&,cloneSpritePtr&,_SWSpriteRec
  558.   '     frame time tasks are unique to each sprite…
  559.   cloneSpritePtr&.frameTimeTask.qLink&  = _nil
  560.   cloneSpritePtr&.frameTimeTask.qType%  = 0
  561.   cloneSpritePtr&.frameTimeTask.tmAddr& = ttPtr&
  562.   cloneSpritePtr&.frameTimeTask.tmCount&= 0
  563.   cloneSpritePtr&.frameTimeTask.tmWakeUp&=0
  564.   cloneSpritePtr&.frameTimeTask.tmReserved&=0
  565.   cloneSpritePtr&.frameTTHasFired%      = _zTrue
  566.   cloneSpritePtr&.frameTimeInterval%    = 0
  567.   '     so are mask regions…
  568.   ' ••••
  569.   cloneSpritePtr&.maskRegionHdl&        = FN NEWRGN
  570.   '     and so are move time tasks…
  571.   cloneSpritePtr&.moveTimeTask.qLink&   = _nil
  572.   cloneSpritePtr&.moveTimeTask.qType%   = 0
  573.   cloneSpritePtr&.moveTimeTask.tmAddr&  = ttPtr&
  574.   cloneSpritePtr&.moveTimeTask.tmCount& = 0
  575.   cloneSpritePtr&.moveTimeTask.tmWakeUp&= 0
  576.   cloneSpritePtr&.moveTimeTask.tmReserved&= 0
  577.   cloneSpritePtr&.moveTTHasFired%       = _zTrue
  578.   cloneSpritePtr&.moveTimeInterval%     = 0
  579.   
  580.   cloneSpritePtr&.isClone%              = _zTrue  'mark sprite as cloned
  581.   
  582.   FN InsXTime(cloneSpritePtr&.frameTimeTask&)     'install time tasks
  583.   FN InsXTime(cloneSpritePtr&.moveTimeTask&)
  584. END FN
  585. '
  586. '---------------------------------------------------------------------
  587. '       SWSpriteFromPict
  588. '---------------------------------------------------------------------
  589. '
  590. '     Inits a Sprite based on pictID (that is, its curRect field is based
  591. '     on the size of pictID, offset to curX,curY.  Returns resErr.
  592. '
  593. LOCAL MODE
  594. DIM frameRect.8
  595. LOCAL FN SWSpriteFromPict(spritePtr&,curFrame,curX,curY,boundsRectP&,vis,xDelta,yDelta,frameAdvance,ttPtr&,movePtr&,pictID)
  596.   '
  597.   pict&  = FN GETPICTURE(pictID) : resErr = FN RESERROR
  598.   '
  599.   LONG IF resErr = _noErr
  600.     frameRect;8 = [pict&]+_picFrame               'pin rect to curX,curY…
  601.     FN FastOffsetRect(frameRect,curX-frameRect.left%,curY-frameRect.top%)
  602.     FN SWInitSprite(spritePtr&,curFrame,@frameRect,boundsRectP&,vis,xDelta,yDelta,frameAdvance,ttPtr&,movePtr&)
  603.     CALL RELEASERESOURCE(pict&)
  604.   END IF
  605.   '
  606. END FN = resErr
  607. '
  608. '---------------------------------------------------------------------
  609. '       SWAddSpriteToLayer
  610. '---------------------------------------------------------------------
  611. '
  612. '     Adds spritePtr& to the specified layer.
  613. '
  614. LOCAL MODE
  615. LOCAL FN SWAddSpriteToLayer(layerPtr&,spritePtr&)
  616.   '
  617.   LONG IF layerPtr&.totalSprites% < _maxSprites
  618.     err = _NoErr
  619.     offset=layerPtr&.totalSprites%*4
  620.     POKE LONG layerPtr&+_spriteList+offset,spritePtr&
  621.     INC(layerPtr&.totalSprites%)
  622.   XELSE
  623.     err=_swTooManySprites
  624.   END IF
  625.   '
  626. END FN = err
  627.  
  628. '---------------------------------------------------------------------
  629. '       SWSetSpriteMoveProc
  630. '---------------------------------------------------------------------
  631. '
  632. '     Sets the movement procedure for a sprite.
  633. '
  634. LOCAL MODE
  635. LOCAL FN SWSetSpriteMoveProc(spritePtr&,moveProcPtr&)
  636.   spritePtr&.moveProcPtr& = moveProcPtr&
  637. END FN
  638. '
  639. '---------------------------------------------------------------------
  640. '       SWSetCollideProc
  641. '---------------------------------------------------------------------
  642. '
  643. '     Set the collide procedure for a sprite.
  644. '
  645. LOCAL MODE
  646. LOCAL FN SWSetCollideProc(spritePtr&,collideProcPtr&)
  647.   spritePtr&.collideProcPtr& = collideProcPtr&
  648. END FN
  649. '
  650. '---------------------------------------------------------------------
  651. '       SWSetFrameChangeProc
  652. '---------------------------------------------------------------------
  653. '
  654. '     Sets the frame change procedure for a sprite.
  655. '
  656. LOCAL MODE
  657. LOCAL FN SWSetFrameChangeProc(spritePtr&,frameChangeProcPtr&)
  658.   spritePtr&.frameChangeProcPtr& = frameChangeProcPtr&
  659. END FN
  660. '
  661. '---------------------------------------------------------------------
  662. '       SWSetMoveDelta
  663. '---------------------------------------------------------------------
  664. '
  665. '       Sets the number of pixels a sprite should be moved by
  666. '       SWProcessSpriteWorld horizontally and vertically.
  667. '
  668. LOCAL MODE
  669. LOCAL FN SWSetMoveDelta(spritePtr&,xDelta,yDelta)
  670.   spritePtr&.xDelta% = xDelta
  671.   spritePtr&.yDelta% = yDelta
  672. END FN
  673. '
  674. '---------------------------------------------------------------------
  675. '       SWOffsetSprite
  676. '---------------------------------------------------------------------
  677. '
  678. '     Moves sprite to a relative position on the screen.
  679. '
  680. LOCAL MODE
  681. LOCAL FN SWOffsetSprite(spritePtr&,xDelta,yDelta)
  682.   FN FastOffsetRect(spritePtr&.currentRect%,xDelta,yDelta)
  683.   LONG IF spritePtr&.isVisible%
  684.     spritePtr&.needsToBeErased% = _zTrue
  685.     spritePtr&.needsToBeDrawn%  = _zTrue
  686.   END IF
  687. END FN
  688.  
  689. '---------------------------------------------------------------------
  690. '       SWSetSpriteFrameAdv
  691. '---------------------------------------------------------------------
  692. '
  693. '     Sets the number by which SWProcessSpriteWorld will advance the current
  694. '     frame.
  695. '
  696. LOCAL MODE
  697. LOCAL FN SWSetSpriteFrameAdv(spritePtr&,frameAdv)
  698.   spritePtr&.frameAdvance% = frameAdv
  699. END FN
  700.  
  701. '---------------------------------------------------------------------
  702. '       SWSetCurrentFrame
  703. '---------------------------------------------------------------------
  704. '
  705. '     Sets the sprite's current frame.
  706. '
  707. LOCAL MODE
  708. LOCAL FN SWSetCurrentFrame(spritePtr&,frameNum)
  709.   spritePtr&.currentFrameNum% = frameNum
  710. END FN
  711.  
  712. '---------------------------------------------------------------------
  713. '       SWSetSpriteVisible
  714. '---------------------------------------------------------------------
  715. '
  716. '     Causes a sprite to appear or disappear.
  717. '
  718. LOCAL MODE
  719. LOCAL FN SWSetSpriteVisible(spritePtr&,vis)
  720.   spritePtr&.isVisible%         = vis
  721.   spritePtr&.needsToBeDrawn%    = vis
  722.   spritePtr&.needsToBeErased%   = NOT(vis)
  723. END FN
  724. '
  725. '---------------------------------------------------------------------
  726. '       SWGetCurRect
  727. '---------------------------------------------------------------------
  728. '
  729. '     Returns sprite's currentRect.
  730. '
  731. LOCAL MODE
  732. LOCAL FN SWGetCurRect(spritePtr&,T&)
  733.   T&.Top%;8 = spritePtr&+_currentRect
  734. END FN
  735. '
  736. '---------------------------------------------------------------------
  737. '       SWSetCurRect
  738. '---------------------------------------------------------------------
  739. '
  740. '     Sets current and old rect of sprite.
  741. '
  742. LOCAL MODE
  743. LOCAL FN SWSetCurRect(spritePtr&,T&)
  744.   spritePtr&.currentRect%;8 = T&
  745.   spritePtr&.oldRect%;8     = T&
  746. END FN
  747. '
  748. '---------------------------------------------------------------------
  749. '       SWSetSpriteLocation
  750. '---------------------------------------------------------------------
  751. '
  752. '     Sets current and old location of sprite, based on x,y coordinates.
  753. '
  754. LOCAL MODE
  755. LOCAL FN SWSetSpriteLocation(spritePtr&,x,y)
  756.   FN FastOffsetRect(spritePtr&.currentRect%,x-spritePtr&.currentRect.left%,y-spritePtr&.currentRect.top%)
  757.   spritePtr&.oldRect%;8 = spritePtr&+_currentRect
  758. END FN
  759.  
  760. '---------------------------------------------------------------------
  761. '       SWMoveSpriteRect
  762. '---------------------------------------------------------------------
  763. '
  764. '     Moves sprite to new rectangle.
  765. '
  766. LOCAL MODE
  767. LOCAL FN SWMoveSpriteRect(spritePtr&,T&)
  768.   spritePtr&.currentRect%;8 = T&
  769.   LONG IF spritePtr&.isVisible%
  770.     spritePtr&.needsToBeErased% = _zTrue
  771.     spritePtr&.needsToBeDrawn%  = _zTrue
  772.   END IF
  773. END FN
  774. '
  775. '---------------------------------------------------------------------
  776. '       SWMoveSprite
  777. '---------------------------------------------------------------------
  778. '
  779. '     Moves sprite to new x,y coordinates.
  780. '
  781. LOCAL MODE
  782. LOCAL FN SWMoveSprite(spritePtr&,x,y)
  783.   '
  784.   FN FastOffsetRect(spritePtr&.currentRect%,x-spritePtr&.currentRect.left%,y-spritePtr&.currentRect.top%)
  785.   '
  786.   LONG IF spritePtr&.isVisible%
  787.     spritePtr&.needsToBeErased%  = _zTrue
  788.     spritePtr&.needsToBeDrawn%   = _zTrue
  789.   END IF
  790. END FN
  791. '
  792. '---------------------------------------------------------------------
  793. '       SWSetMoveBounds
  794. '---------------------------------------------------------------------
  795. '
  796. '     Sets the bounding rectangle of the specified sprite.
  797. '
  798. LOCAL MODE
  799. LOCAL FN SWSetMoveBounds(spritePtr&,T&)
  800.   spritePtr&.sBoundsRect%;8 = T&
  801. END FN
  802. '
  803. '---------------------------------------------------------------------
  804. '       SWSetFrameRange
  805. '---------------------------------------------------------------------
  806. '
  807. '     Sets the range of frame indexes to be interated in SWProcessSpriteWorld.
  808. '
  809. LOCAL MODE
  810. LOCAL FN SWSetFrameRange(spritePtr&,firstFrame,lastFrame)
  811.   spritePtr&.firstFrameIndex%  = firstFrame
  812.   spritePtr&.lastFrameIndex%   = lastFrame
  813. END FN
  814. '
  815. '---------------------------------------------------------------------
  816. '       SWIsSpriteInRect
  817. '---------------------------------------------------------------------
  818. '
  819. LOCAL MODE
  820. DIM rect.8
  821. LOCAL FN SWIsSpriteInRect(spritePtr&,rect;8)
  822.   '
  823.   '     Returns _zTrue (-1) if sprite's current rect is equal to or
  824.   '     contained in rect.
  825.   '
  826. END FN = (spritePtr&.currentRect.top%>=rect.top% AND spritePtr&.currentRect.left%>=rect.left% AND spritePtr&.currentRect.bottom%<=rect.bottom% AND spritePtr&.currentRect.right%<=rect.right%)
  827. '
  828. '---------------------------------------------------------------------
  829. '       SWSpriteSectRect
  830. '---------------------------------------------------------------------
  831. '
  832. LOCAL MODE
  833. DIM rect.8
  834. LOCAL FN SWSpriteSectRect(spritePtr&,rect;8,sectRectPtr&)
  835.   '
  836.   '     Returns _zTrue (-1) if the sprite's current rect intersects
  837.   '     rect.  If there is an intersection, sectRect will contain the
  838.   '     intersecting rectangle.
  839.   '
  840. END FN = -(FN SECTRECT(#spritePtr&+_currentRect,rect,#sectRectPtr&))
  841. '
  842. '---------------------------------------------------------------------
  843. '       SWRemoveLayer
  844. '---------------------------------------------------------------------
  845. '
  846. '     Removes a layer from the specified SpriteWorld.
  847. '
  848. LOCAL MODE
  849. LOCAL FN SWRemoveLayer(SWPtr&,layerPtr&)
  850.   '
  851.   FOR x = 0 TO SWPtr&.totalLayers%-1              'find layer in layerlist
  852.     targetLayer& = [SWPtr&+_layerList+(x*4)]
  853.     LONG IF layerPtr& = targetLayer&
  854.       '         delete layer and adjust layerList
  855.       FOR layer = x TO SWPtr&.totalLayers%-2
  856.         &SWPtr&+_layerList+(layer*4),[SWPtr&+_layerList+((layer+1)*4)]
  857.       NEXT
  858.       &SWPtr&+_layerList+((SWPtr&.totalLayers%-1)*4),_nil
  859.       DEC(SWPtr&.totalLayers%)
  860.       EXIT FOR
  861.     END IF
  862.   NEXT
  863.   '
  864. END FN
  865. '
  866. '---------------------------------------------------------------------
  867. '       SWRemoveSprite
  868. '---------------------------------------------------------------------
  869. '
  870. '     Removes a sprite from the specified layer.
  871. '     Does not dispose of the sprite.
  872. '
  873. LOCAL MODE
  874. LOCAL FN SWRemoveSprite(layerPtr&,spritePtr&)
  875.   '
  876.   FOR x = 0 TO layerPtr&.totalSprites%-1          'find sprite in spritelist
  877.     targetSprite& = [layerPtr&+_spriteList+(x*4)]
  878.     LONG IF spritePtr& = targetSprite&
  879.       '         delete sprite and adjust spriteList
  880.       FOR sprite=x TO layerPtr&.totalSprites%-2
  881.         &layerPtr&+_spriteList+(sprite*4),[layerPtr&+_spriteList+((sprite+1)*4)]
  882.       NEXT
  883.       &layerPtr&+_spriteList+((layerPtr&.totalSprites%-1)*4),_nil
  884.       DEC(layerPtr&.totalSprites%)
  885.       EXIT FOR
  886.     END IF
  887.   NEXT
  888.   '
  889. END FN
  890. '
  891. '---------------------------------------------------------------------
  892. '       SWRemoveFrame
  893. '---------------------------------------------------------------------
  894. '
  895. '       Removes a frame from the specified sprite.
  896. '       Does not dispose of the frame.
  897. '
  898. LOCAL MODE
  899. LOCAL FN SWRemoveFrame(spritePtr&,framePtr&)
  900.   '
  901.   FOR x = 0 TO spritePtr&.totalFrames%-1          'find frame in framelist
  902.     targetFrame& = [spritePtr&+_frameList+(x*4)]
  903.     LONG IF framePtr& = targetFrame&
  904.       '         delete frame and adjust frameList
  905.       FOR frame = x TO spritePtr&.totalFrames%-2
  906.         &spritePtr&+_frameList+(frame*4),[spritePtr&+_frameList+((frame+1)*4)]
  907.       NEXT
  908.       &spritePtr&+_frameList+((spritePtr&.totalFrames%-1)*4),_nil
  909.       DEC(spritePtr&.totalFrames%)
  910.       '         adjust lastFrameIndex, if necessary
  911.       IF spritePtr&.totalFrames%<spritePtr&.lastFrameIndex% THEN spritePtr&.lastFrameIndex%=spritePtr&.totalFrames%
  912.       EXIT FOR
  913.     END IF
  914.   NEXT
  915.   '
  916. END FN
  917. '
  918. '---------------------------------------------------------------------
  919. '       SWIsTaskPrimed
  920. '---------------------------------------------------------------------
  921. '
  922. LOCAL MODE
  923. LOCAL FN SWIsTaskPrimed(tmTaskPtr&)
  924.   '
  925.   '     Returns _zTrue if timeTask has been primed.
  926.   '
  927. END FN = (tmTaskPtr&.qType% AND &8000) <> 0
  928. '
  929. '---------------------------------------------------------------------
  930. '       SWSetFrameTime
  931. '---------------------------------------------------------------------
  932. '
  933. '     Sets the time in milliseconds between frame changes.
  934. '
  935. LOCAL MODE
  936. LOCAL FN SWSetFrameTime(spritePtr&,timeInterval)
  937.   '
  938.       spritePtr&.frameTimeInterval% = timeInterval
  939.       LONG IF timeInterval > 0
  940.     LONG IF FN SWIsTaskPrimed(spritePtr&.frameTimeTask&)=0'if task not primed…
  941.       spritePtr&.frameTTHasFired% = _zTrue        '…prime it
  942.     END IF
  943.       XELSE
  944.     LONG IF timeInterval < 0                      'is the time interval negative?
  945.       LONG IF FN SWIsTaskPrimed(spritePtr&.frameTimeTask&)'if the task is primed…
  946.         FN RmvTime(spritePtr&.frameTimeTask&)     '…remove it
  947.         FN InsXTime(spritePtr&.frameTimeTask&)
  948.       END IF
  949.       ' the timeInterval is negative, which means never change the frame
  950.       spritePtr&.frameTTHasFired% = _false
  951.     XELSE
  952.       ' time interval=0; this means change frames as quickly as possible
  953.       spritePtr&.frameTTHasFired% = _zTrue
  954.     END IF
  955.   END IF
  956.   '
  957. END FN
  958. '
  959. '---------------------------------------------------------------------
  960. '       SWSetMoveTime
  961. '---------------------------------------------------------------------
  962. '
  963. '       Sets the time in milliseconds between sprite moves.
  964. '
  965. LOCAL MODE
  966. LOCAL FN SWSetMoveTime(spritePtr&,timeInterval)
  967.   '
  968.   spritePtr&.moveTimeInterval% = timeInterval
  969.   '
  970.       LONG IF timeInterval > 0
  971.     LONG IF FN SWIsTaskPrimed(spritePtr&.moveTimeTask&)=0'if task not primed…
  972.       spritePtr&.moveTTHasFired% = _zTrue         '…prime it
  973.     END IF
  974.       XELSE 
  975.     LONG IF timeInterval < 0                      'is the time interval negative?
  976.       LONG IF FN SWIsTaskPrimed(spritePtr&.moveTimeTask&)'if the task is primed…
  977.         FN RmvTime(spritePtr&.moveTimeTask&)      'remove it
  978.         FN InsXTime(spritePtr&.moveTimeTask&)
  979.       END IF
  980.       '
  981.       '         the timeInterval is negative, which means never move sprite
  982.       '
  983.       spritePtr&.moveTTHasFired% = _false
  984.     XELSE
  985.       '
  986.       '         time interval=0; this means move sprite as quickly as possible
  987.       '
  988.       spritePtr&.moveTTHasFired% = _zTrue
  989.     END IF
  990.   END IF
  991. END FN
  992. '
  993. '---------------------------------------------------------------------
  994. '       SWUpdateSpriteWorld
  995. '---------------------------------------------------------------------
  996. '
  997. '     Copies entire loadframe to screen.
  998. '     Used to refesh screen following an update event.
  999. '
  1000. LOCAL MODE
  1001. LOCAL FN SWUpdateSpriteWorld(SWPtr&)
  1002.   FN CopyOffScreenBits(SWPtr&.loadFramePtr&,SWPtr&.windowFramePtr&,SWPtr&+_boundsRect,SWPtr&+_boundsRect,_srcCopy,_nil)
  1003. END FN
  1004. '
  1005. '---------------------------------------------------------------------
  1006. '       SWCollideSpriteLayer
  1007. '---------------------------------------------------------------------
  1008. '
  1009. '     Detects collisions between sprites in srcLayer and sprites in
  1010. '     destLayer.  If collision is detected, calls collideProc of srcSprite.
  1011. '     To detect collisions between sprites in the same layer, pass the
  1012. '     same layer variable in both srcLayerPtr& and destLayerPtr&.
  1013. '
  1014. LOCAL MODE
  1015. DIM sectRect.8
  1016. LOCAL FN SWCollideSpriteLayer(srcLayerPtr&,destLayerPtr&)
  1017.   '
  1018.   FOR srcSprite = 0 TO srcLayerPtr&.totalSprites%-1
  1019.     srcSpritePtr& = [srcLayerPtr&+_spriteList+(srcSprite*4)]
  1020.     '
  1021.     FOR destSprite = 0 TO destLayerPtr&.totalSprites%-1
  1022.       destSpritePtr& = [destLayerPtr&+_spriteList+(destSprite*4)]
  1023.       LONG IF srcSpritePtr& <> destSpritePtr&
  1024.         LONG IF FN SECTRECT(#srcSpritePtr&+_currentRect,#destSpritePtr&+_currentRect,sectRect)
  1025.           collideProcPtr& = srcSpritePtr&.collideProcPtr&
  1026.           IF collideProcPtr& THEN CALL collideProcPtr&(srcSpritePtr&,destSpritePtr&,@sectRect)
  1027.         END IF
  1028.       END IF
  1029.     NEXT
  1030.     '
  1031.   NEXT
  1032.   '
  1033. END FN
  1034. '
  1035. '•      •       •       •       •       •       •       •       •       •
  1036.  
  1037.